// 位置服务工具

// 位置追踪配置
const LOCATION_UPDATE_INTERVAL = 5000 // 位置更新间隔（毫秒）
const MIN_DISTANCE_CHANGE = 10 // 最小距离变化（米）才触发更新

// 位置追踪状态
let locationTracker = {
  isTracking: false,
  intervalId: null,
  lastLocation: null,
  updateCallback: null,
  errorCallback: null
}

/**
 * 请求位置权限
 * 需求 4.1: 请求位置访问权限并说明使用目的
 * 需求 4.2: 用户授予权限时，启用位置追踪功能
 * 需求 4.4: 用户拒绝权限时，禁用需要位置的功能
 * @param {boolean} showExplanation - 是否显示详细说明
 * @returns {Promise<{granted: boolean, reason: string}>}
 */
function requestLocationPermission(showExplanation = false) {
  return new Promise((resolve, reject) => {
    wx.getSetting({
      success: (res) => {
        if (res.authSetting['scope.userLocation']) {
          // 需求 4.2: 已授权，启用位置追踪功能
          resolve({ granted: true, reason: 'already_granted' })
        } else if (res.authSetting['scope.userLocation'] === false) {
          // 需求 4.4: 用户已拒绝，需要引导到设置页面
          wx.showModal({
            title: '需要位置权限',
            content: '步语需要获取您的位置信息来规划散步路线、推荐附近景点并提供实时导航服务。请在设置中开启位置权限。',
            confirmText: '去设置',
            cancelText: '取消',
            success: (modalRes) => {
              if (modalRes.confirm) {
                wx.openSetting({
                  success: (settingRes) => {
                    if (settingRes.authSetting['scope.userLocation']) {
                      // 需求 4.2: 用户在设置中授予权限，启用位置追踪功能
                      resolve({ granted: true, reason: 'granted_in_settings' })
                    } else {
                      // 需求 4.4: 用户仍未授权，禁用需要位置的功能
                      resolve({ granted: false, reason: 'denied_in_settings' })
                    }
                  },
                  fail: () => resolve({ granted: false, reason: 'settings_open_failed' })
                })
              } else {
                // 需求 4.4: 用户取消去设置，禁用需要位置的功能
                resolve({ granted: false, reason: 'user_cancelled_settings' })
              }
            }
          })
        } else {
          // 首次请求权限
          if (showExplanation) {
            // 显示详细说明后再请求
            wx.showModal({
              title: '位置权限说明',
              content: '步语需要获取您的位置信息来提供以下功能：\n\n1. 规划个性化散步路线\n2. 推荐附近景点\n3. 实时导航和景点介绍\n4. 记录散步足迹\n\n我们承诺：\n• 仅在使用期间获取位置\n• 不会分享给第三方\n• 您可以随时关闭权限',
              confirmText: '授权',
              cancelText: '取消',
              success: (modalRes) => {
                if (modalRes.confirm) {
                  // 用户同意后请求权限
                  wx.authorize({
                    scope: 'scope.userLocation',
                    success: () => {
                      // 需求 4.2: 用户授予权限时，启用位置追踪功能
                      resolve({ granted: true, reason: 'granted_after_explanation' })
                    },
                    fail: () => {
                      // 需求 4.4: 用户拒绝授权，禁用需要位置的功能
                      resolve({ granted: false, reason: 'denied_after_explanation' })
                    }
                  })
                } else {
                  // 需求 4.4: 用户取消授权，禁用需要位置的功能
                  resolve({ granted: false, reason: 'cancelled_explanation' })
                }
              }
            })
          } else {
            // 直接请求权限
            wx.authorize({
              scope: 'scope.userLocation',
              success: () => {
                // 需求 4.2: 用户授予权限时，启用位置追踪功能
                resolve({ granted: true, reason: 'granted_first_time' })
              },
              fail: () => {
                // 需求 4.4: 用户拒绝授权，显示说明并禁用需要位置的功能
                wx.showModal({
                  title: '位置权限说明',
                  content: '步语需要获取您的位置信息来提供以下功能：\n1. 规划个性化散步路线\n2. 推荐附近景点\n3. 实时导航和景点介绍\n4. 记录散步足迹\n\n没有位置权限，这些功能将无法使用。',
                  showCancel: false,
                  confirmText: '我知道了'
                })
                resolve({ granted: false, reason: 'denied_first_time' })
              }
            })
          }
        }
      },
      fail: () => {
        reject(new Error('获取权限设置失败'))
      }
    })
  })
}

/**
 * 检查位置权限状态
 * @returns {Promise<{hasPermission: boolean, status: string}>}
 */
function checkLocationPermission() {
  return new Promise((resolve, reject) => {
    wx.getSetting({
      success: (res) => {
        if (res.authSetting['scope.userLocation']) {
          resolve({ hasPermission: true, status: 'granted' })
        } else if (res.authSetting['scope.userLocation'] === false) {
          resolve({ hasPermission: false, status: 'denied' })
        } else {
          resolve({ hasPermission: false, status: 'not_requested' })
        }
      },
      fail: () => {
        reject(new Error('检查权限状态失败'))
      }
    })
  })
}

/**
 * 获取当前位置
 * @returns {Promise<object>}
 */
function getCurrentLocation() {
  return new Promise((resolve, reject) => {
    wx.getLocation({
      type: 'gcj02', // 使用国测局坐标系
      altitude: true, // 获取海拔信息
      success: (res) => {
        const location = {
          latitude: res.latitude,
          longitude: res.longitude,
          accuracy: res.accuracy,
          altitude: res.altitude || null
        }
        resolve(location)
      },
      fail: (err) => {
        console.error('获取位置失败:', err)
        reject(err)
      }
    })
  })
}

/**
 * 开始位置追踪
 * 需求 4.3: 以适当的频率更新用户位置
 * @param {Function} onUpdate - 位置更新回调函数 (location) => void
 * @param {Function} onError - 错误回调函数 (error) => void
 * @param {Object} options - 配置选项
 * @param {number} options.interval - 更新间隔（毫秒），默认5000
 * @param {number} options.minDistance - 最小距离变化（米），默认10
 * @returns {Promise<boolean>} 是否成功启动追踪
 */
async function startLocationTracking(onUpdate, onError, options = {}) {
  // 如果已在追踪，先停止
  if (locationTracker.isTracking) {
    stopLocationTracking()
  }

  // 检查权限
  const permissionResult = await requestLocationPermission()
  if (!permissionResult.granted) {
    if (onError) {
      onError(new Error(`位置权限未授予: ${permissionResult.reason}`))
    }
    return false
  }

  // 配置参数
  const interval = options.interval || LOCATION_UPDATE_INTERVAL
  const minDistance = options.minDistance || MIN_DISTANCE_CHANGE

  // 设置回调
  locationTracker.updateCallback = onUpdate
  locationTracker.errorCallback = onError
  locationTracker.isTracking = true

  // 立即获取一次位置
  try {
    const location = await getCurrentLocation()
    locationTracker.lastLocation = location
    if (onUpdate) {
      onUpdate(location)
    }
  } catch (err) {
    console.error('初始位置获取失败:', err)
    if (onError) {
      onError(err)
    }
  }

  // 启动定时更新
  locationTracker.intervalId = setInterval(async () => {
    try {
      const newLocation = await getCurrentLocation()
      
      // 检查距离变化
      if (locationTracker.lastLocation) {
        const distance = calculateDistance(
          locationTracker.lastLocation.latitude,
          locationTracker.lastLocation.longitude,
          newLocation.latitude,
          newLocation.longitude
        )
        
        // 只有移动距离超过阈值才触发更新
        if (distance >= minDistance) {
          locationTracker.lastLocation = newLocation
          if (locationTracker.updateCallback) {
            locationTracker.updateCallback(newLocation)
          }
        }
      } else {
        locationTracker.lastLocation = newLocation
        if (locationTracker.updateCallback) {
          locationTracker.updateCallback(newLocation)
        }
      }
    } catch (err) {
      console.error('位置更新失败:', err)
      if (locationTracker.errorCallback) {
        locationTracker.errorCallback(err)
      }
    }
  }, interval)

  return true
}

/**
 * 停止位置追踪
 * 需求 4.5: 散步会话结束时停止持续的位置追踪
 */
function stopLocationTracking() {
  if (locationTracker.intervalId) {
    clearInterval(locationTracker.intervalId)
    locationTracker.intervalId = null
  }
  
  locationTracker.isTracking = false
  locationTracker.lastLocation = null
  locationTracker.updateCallback = null
  locationTracker.errorCallback = null
}

/**
 * 获取位置追踪状态
 * @returns {boolean}
 */
function isLocationTracking() {
  return locationTracker.isTracking
}

/**
 * 获取最后已知位置
 * @returns {object|null}
 */
function getLastKnownLocation() {
  return locationTracker.lastLocation
}

/**
 * 计算两点间距离（米）
 * 使用 Haversine 公式
 * @param {number} lat1 
 * @param {number} lon1 
 * @param {number} lat2 
 * @param {number} lon2 
 * @returns {number}
 */
function calculateDistance(lat1, lon1, lat2, lon2) {
  const R = 6371e3 // 地球半径（米）
  const φ1 = lat1 * Math.PI / 180
  const φ2 = lat2 * Math.PI / 180
  const Δφ = (lat2 - lat1) * Math.PI / 180
  const Δλ = (lon2 - lon1) * Math.PI / 180

  const a = Math.sin(Δφ / 2) * Math.sin(Δφ / 2) +
    Math.cos(φ1) * Math.cos(φ2) *
    Math.sin(Δλ / 2) * Math.sin(Δλ / 2)
  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))

  return R * c
}

module.exports = {
  requestLocationPermission,
  checkLocationPermission,
  getCurrentLocation,
  startLocationTracking,
  stopLocationTracking,
  isLocationTracking,
  getLastKnownLocation,
  calculateDistance
}
